<?php

namespace backend\controllers;

use Yii;
use yii\web\Controller;
use yii\web\NotFoundHttpException;
use yii\filters\VerbFilter;
use yii\web\UploadedFile;
use backend\components\Installer;
use common\components\Helper;
use backend\models\Extensions;
use backend\models\searchs\Extensions as ExtensionsSearch;
use backend\models\UploadForm;

/**
 * ExtensionsController implements the CRUD actions for Extensions model.
 */
class ExtensionsController extends Controller
{
    /**
     * {@inheritdoc}
     */
    public function behaviors()
    {
        return [
            'verbs' => [
                'class' => VerbFilter::class,
                'actions' => [
                    'delete' => ['POST'],
                ],
            ],
        ];
    }

    public function beforeAction($action)
    {
        if (parent::beforeAction($action)) {
            Helper::addEntry('扩展安装', ['/extensions/installer'], 'installer');
            Helper::addEntry('扩展升级', ['/extensions/update'], 'update');
            Helper::addEntry('扩展管理', ['/extensions/manage'], 'manage');
            Helper::addEntry('数据库维护', ['/extensions/database'], 'database');
            Helper::addEntry('语言安装', ['/extensions/languages'], 'languages');
            Helper::addEntry('升级检查', ['/extensions/updatesites'], 'updatesites');
            return true;
        }
        return false;
    }

    /**
     * 扩展安装
     * @return mixed
     * @throws yii\base\ErrorException
     */
    public function actionInstaller()
    {
        $model = new UploadForm(['exts' => 'zip, rar, tar']);
        $request = Yii::$app->request;
        $session = Yii::$app->session;
        if ($request->isPost) {
            if ($request->post('action') === 'continue') {
                $installRes = Installer::install();
                $this->installedAfter($installRes);
            } else {
                $model->file = UploadedFile::getInstance($model, 'file');
                if ($model->upload('', true)) {
                    $filePath = $model->path . $model->file->name;
                    $installer = new Installer();
                    $ExtensionId = $installer->install($filePath);
                    $this->installedAfter($ExtensionId);
                } else {
                    $session->setFlash('error', Helper::errorsToString($model->errors));
                }
            }
            return $this->redirect(['installer']);
        }

        return $this->render('installer', ['model' => $model]);
    }

    /**
     * Lists all Extensions models.
     * @return mixed
     */
    public function actionManage()
    {
        $request = Yii::$app->request;
        $session = Yii::$app->session;
        if ($request->isPost) {
            $post = $request->post();
            if (isset($post['selection'])) {
                $status = $post['action'] === 'enable' ? 0 : ($post['action'] === 'disable' ? 1 : null);
                if ($status === null) {
                    if ($post['action'] === 'uninstall') {
                        $installer = new Installer();
                        $installer->uninstall($post['selection']);
                    } else {
                        $session->setFlash('error', Yii::t('yii', 'INVALID_DATA_PARAMETER', [
                            'param' => 'action'
                        ]));
                    }
                } else {
                    $extensions = Extensions::find()->where([
                        'id' => $post['selection'],
                        'protected' => 0,
                        'status' => $status
                    ])->all();
                    if (count($extensions) > 0) {
                        foreach ($extensions as $extension) {
                            $extension->status = abs($extension->status - 1);
                            $extension->save();
                        }
                    }

                    $message = $status ? 'EXTENSION_DISABLED_NUM' : 'EXTENSION_ENABLED_NUM';
                    $session->setFlash('success', Yii::t('extensions', $message, count($extensions)));
                }
            } else {
                $extensions = Extensions::findOne(['id' => $post['id'], 'protected' => 0]);
                if ($extensions !== null) {
                    $extensions->status = $extensions->status ? 0 : 1;
                    if ($extensions->save()) {
                        $success = [
                            'enabled' => Yii::t('extensions', 'EXTENSION_ENABLED_NUM', '1'),
                            'disabled' => Yii::t('extensions', 'EXTENSION_DISABLED_NUM', '1')
                        ];
                        $session->setFlash('success', $extensions->status ? $success['enabled'] : $success['disabled']);
                    } else {
                        $fail = [
                            'enabled' => Yii::t('extensions', 'EXTENSION_ENABLED_FAILED'),
                            'disabled' => Yii::t('extensions', 'EXTENSION_DISABLED_FAILED')
                        ];
                        $session->setFlash('error', $extensions->status ? $fail['disabled'] : $fail['enabled']);
                    }
                } else {
                    $session->setFlash('warning', Yii::t('extensions', 'EXTENSIONS_NOT_EXIST_OR_PROTECTED'));
                }
            }
        }

        $searchModel = new ExtensionsSearch();
        $dataProvider = $searchModel->search(Yii::$app->request->queryParams);

        return $this->render('manage', [
            'searchModel' => $searchModel,
            'dataProvider' => $dataProvider,
        ]);
    }

    /**
     * Updates an existing Extensions model.
     * If update is successful, the browser will be redirected to the 'view' page.
     * @param integer $id
     * @return mixed
     * @throws NotFoundHttpException if the model cannot be found
     */
    public function actionUpdate($id)
    {
        $model = $this->findModel($id);

        if ($model->load(Yii::$app->request->post()) && $model->save()) {
            return $this->redirect(['view', 'id' => $model->id]);
        }

        return $this->render('update', ['model' => $model]);
    }

    /**
     * Finds the Extensions model based on its primary key value.
     * If the model is not found, a 404 HTTP exception will be thrown.
     * @param integer $id
     * @return Extensions the loaded model
     * @throws NotFoundHttpException if the model cannot be found
     */
    protected function findModel($id)
    {
        if (($model = Extensions::findOne($id)) !== null) {
            return $model;
        }

        throw new NotFoundHttpException(Yii::t('common', 'REQUESTED_PAGE_NOT_EXIST'));
    }

    /**
     * 安装完成操作
     * @param int|boolean $extensionId 扩展ID
     */
    private function installedAfter($extensionId)
    {
        if (false !== $extensionId) {
            $extension = Extensions::findOne($extensionId);
            $session = Yii::$app->session;
            $session->setFlash('success', Yii::t('extensions', 'EXTENSION_INSTALLATION_SUCCESSFUL', [
                'name' => Yii::t('extensions', strtoupper($extension->type))
            ]));
            $langCat = $extension->manifest_cache['langCat'] ?? false;
            $description = trim($extension->manifest_cache['description']);

            if ($extension->type == 'theme') {
                $client = \backend\models\Clients::findOne($extension->client_id);
                $messageBasePath = '@' . $client->name . '/themes/' . $extension->element . '/messages';
            } else {
                $messageBasePath = '@backend/messages';
            }

            Yii::$app->i18n->translations[$langCat] = [
                'class' => 'yii\i18n\PhpMessageSource',
                'basePath' => $messageBasePath
            ];

            $message = $langCat ? Yii::t($langCat, $description) : $description;

            $session->setFlash('panel', $message);
        }
    }

}
